iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
Modern Web

快搭上姐姐的`微`前端便車系列 第 23

第23車廂-在網頁中預覽pdf—pdf.js簡易版應用篇

  • 分享至 

  • xImage
  •  

本篇介紹JS插件pdf.js簡易應用篇

今天介紹透過插件pdf.js在網頁中直接瀏覽pdf
https://ithelp.ithome.com.tw/upload/images/20211008/20142016hPDINNtRe9.jpg
官網: https://mozilla.github.io/pdf.js/
官網範例:https://mozilla.github.io/pdf.js/examples/

起手式

介紹Dounload版的,因為CDN版的話官網有介紹
首先下載至電腦
https://ithelp.ithome.com.tw/upload/images/20211008/20142016un2hPYjESY.jpg

其他下載方式可看 https://mozilla.github.io/pdf.js/getting_started/

▼ 本地下載之後,資料匣名稱為"pdfjs-2.10.377-dist.zip"
解壓縮後 > 新增一專案資料夾 > 將下載包 放到Visual Studio Code執行

本篇分享兩種
1.使用Pdf.js 的 viewer.js 可以直接有放大縮小列印等功能
2.使用Pdf.js 搭配官網範例js 將PDF文件渲染成Canvas

1.viewer.js

整體資料匣 + 要用的東西

https://ithelp.ithome.com.tw/upload/images/20211008/20142016cpKNEVKHtx.png

引入

  • "pdfjs-2.10.377-dist.zip" 我改命名為"pdfjs-dist" (不一定要改名字)
  <link rel="stylesheet"
        href="pdfjs-dist/web/viewer.css"> //pdf查看器樣式
  <link rel="stylesheet"
        href="pdfjs-dist/web/locale/locale.properties"> //資源文件

  <script src="pdfjs-dist/build/pdf.js"></script> // 核心
  <script src="pdfjs-dist/web/viewer.js"></script> // viewer.html是pdf查看器

https://ithelp.ithome.com.tw/upload/images/20211008/20142016ClNSV18S2H.jpg

使用iframe嵌入在網頁中

HTML
src="pdfjs-dist/web/viewer.html?file=/pdf/五倍券懶人包.pdf"
/pdf/五倍券懶人包.pdf 為我自己資料匣要抓的pdf檔案路徑
pdfjs-dist/web/viewer.html?file= 前面要加這段,pdfjs-dist/是我下載包的資料匣名稱

<div style="width: 80%;margin: auto;">
    <iframe src="pdfjs-dist/web/viewer.html?file=/pdf/五倍券懶人包.pdf"
            width="100%"
            height="500px"
            frameborder="0"
            border="0"
            cellspacing="0"></iframe>
  </div>

這樣就完成啦!
https://ithelp.ithome.com.tw/upload/images/20211008/20142016aVrHUVAytT.jpg

2.渲染成canvas

整體資料匣 + 要用的東西

https://ithelp.ithome.com.tw/upload/images/20211008/20142016DgJKfinsyi.png

引入

  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js'></script>
  <script src="pdfjs-dist/build/pdf.js"></script>
  <script src="runpdf.js"></script> // 為自行新增的js

HTML

  • 預先準備好容器canvas
<div>
  <button id="prev">上一頁</button>
  <button id="next">下一頁</button>
     
  <span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>

<canvas id="the-canvas" ></canvas>

JS (我資料匣命名為runpdf.js)

  • var url = 'pdf/compressed.pdf'; //這邊是要秀的pdf
  • pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js'; //這邊抓資料匣命名的bulid底下的worker.js
  • scale 可以調整
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
var url = 'pdf/compressed.pdf'; //這邊是要秀的pdf

$(function() {
// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];

// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js'; //這邊抓我資料匣命名的bulid底下的worker.js

var pdfDoc = null,
    pageNum = 1,
    pageRendering = false,
    pageNumPending = null,
    scale = 1 // 這邊可以縮放
    canvas = document.getElementById('the-canvas'), // 抓html ID
    ctx = canvas.getContext('2d');

/**
 * Get page info from document, resize canvas accordingly, and render page.
 * @param num Page number.
 */
function renderPage(num) {
  pageRendering = true;
  // Using promise to fetch the page
  pdfDoc.getPage(num).then(function(page) {
    var viewport = page.getViewport({scale: scale});
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    // Render PDF page into canvas context
    var renderContext = {
      canvasContext: ctx,
      viewport: viewport
    };
    var renderTask = page.render(renderContext);

    // Wait for rendering to finish
    renderTask.promise.then(function() {
      pageRendering = false;
      if (pageNumPending !== null) {
        // New page rendering is pending
        renderPage(pageNumPending);
        pageNumPending = null;
      }
    });
  });

  // Update page counters
  document.getElementById('page_num').textContent = num;
}

/**
 * If another page rendering in progress, waits until the rendering is
 * finised. Otherwise, executes rendering immediately.
 */
function queueRenderPage(num) {
  if (pageRendering) {
    pageNumPending = num;
  } else {
    renderPage(num);
  }
}

/**
 * Displays previous page.
 */
function onPrevPage() {
  if (pageNum <= 1) {
    return;
  }
  pageNum--;
  queueRenderPage(pageNum);
}
document.getElementById('prev').addEventListener('click', onPrevPage);

/**
 * Displays next page.
 */
function onNextPage() {
  if (pageNum >= pdfDoc.numPages) {
    return;
  }
  pageNum++;
  queueRenderPage(pageNum);
}
document.getElementById('next').addEventListener('click', onNextPage);

/**
 * Asynchronously downloads PDF.
 */
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
  pdfDoc = pdfDoc_;
  document.getElementById('page_count').textContent = pdfDoc.numPages;

  // Initial/first page rendering
  renderPage(pageNum);
});
});

https://ithelp.ithome.com.tw/upload/images/20211008/20142016t1wDEbqprY.png
這樣就完成啦! ▲ 此段js基本上是透過官網範例貼上

注意使用canvas產生的pdf會較模糊,目前網路上找了一下解法,我是還沒找到一個完美的解答,如果你知道也請留言在下方,感謝

  • 如果大家只是要簡易的用,目前我是透過調整scale的大小,就會比較清晰,如果你的canvas是隨著螢幕縮放,就要按照比例調整,或者找更適合的解法

本篇參考文章:
https://codingnote.cc/zh-tw/p/18741/


上一篇
第22車廂-模仿大賽—仿IT邦幫忙:Sticky Nav應用篇
下一篇
第24車廂-翻起來惹!頁面翻頁效果turn.js應用篇
系列文
快搭上姐姐的`微`前端便車30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言